/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package eu.xibit.jsimpleportforward;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author David
 */
public class CommThread {
	
	private static ArrayList<CommThread> commThreads = new ArrayList<CommThread>();
	
	public static void stopAll() {
		CommThread[] trds = commThreads.toArray(new CommThread[0]);
		for (CommThread t : trds) {
			t.stop();
		}
	}
	
	private final Socket sourceSocket;
	private final int targetPort;
	private Socket targetSocket;
	
	private Thread sendThread;
	private Thread receiveThread;
	
	private boolean stopped = false;

	public CommThread(Socket sourceSocket, int targetPort) throws IOException {
		this.sourceSocket = sourceSocket;
		this.targetPort = targetPort;
		commThreads.add(this);
		this.targetSocket = new Socket("localhost", targetPort);
	}
	
	public void stop() {
		this.stopped = true;
		commThreads.remove(this);
	}
	
	public void start() {
		this.sendThread = new Thread(new Runnable() {

			@Override
			public void run() {
				InputStream is = null;
				OutputStream os = null;
				try {
					is = sourceSocket.getInputStream();
					os = targetSocket.getOutputStream();
					byte[] buff = new byte[65536];
					int readed = 0;
					while ((readed = is.read(buff)) > 0) {
						os.write(buff, 0, readed);
					}
				} catch (IOException ex) {
					//Logger.getLogger(CommThread.class.getName()).log(Level.SEVERE, null, ex);
				} finally {
					stopped = true;
					if (is != null) {
						try {
							is.close();
						} catch (IOException ex) {
							// who cares
						}
					}
					if (os != null) {
						try {
							os.close();
						} catch (IOException ex) {
							// who cares
						}
					}
					System.out.println("Send thread stopped.");
				}
				
			}
		}, "TSend");
		this.receiveThread = new Thread(new Runnable() {

			@Override
			public void run() {
				InputStream is = null;
				OutputStream os = null;
				try {
					is = targetSocket.getInputStream();
					os = sourceSocket.getOutputStream();
					byte[] buff = new byte[65536];
					int readed = 0;
					while ((readed = is.read(buff)) > 0) {
						os.write(buff, 0, readed);
					}
				} catch (IOException ex) {
					//Logger.getLogger(CommThread.class.getName()).log(Level.SEVERE, null, ex);
				} finally {
					stopped = true;
					if (is != null) {
						try {
							is.close();
						} catch (IOException ex) {
							// who cares
						}
					}
					if (os != null) {
						try {
							os.close();
						} catch (IOException ex) {
							// who cares
						}
					}
					System.out.println("Receive thread stopped.");
				}
			}
		}, "TReceive");
		sendThread.start();
		receiveThread.start();
		System.out.println("CommThread started.");
	}
	
	
}
